﻿using CoreDomain.BusinessCore;
using DomainService.IService;
using DomainService.IService.Sys;
using Infrastructure;
using Infrastructure.IRepository.Sys;
using Microsoft.CodeAnalysis;
using Model;
using Model.BusinessModel;
using Model.BusinessModel.InPut;
using Model.BusinessModel.OutPut;
using Model.DomainModel.Sys;
using Newtonsoft.Json.Linq;
using System.Data;
using System.Linq.Dynamic.Core;
using Utility;
using Utility.Enum;

namespace DomainService.Service.Sys
{
    /// <summary>
    /// 用户服务接口实现
    /// </summary>
    public class SysUserService : ISysUserService
    {
        #region 构造实例化

        /// <summary>
        /// 用户底层仓储
        /// </summary>
        private readonly ISysUserRepository _sysUserRepository;

        /// <summary>
        /// 公司底层仓储
        /// </summary>
        private readonly ISysCorporationRepository _sysCorporationRepository;

        /// <summary>
        /// 系统底层仓储
        /// </summary>
        private readonly ISysSystemRepository _sysSystemRepository;

        /// <summary>
        /// 用户角色关系仓储
        /// </summary>
        private readonly ISysUserRoleRelationRepository _sysUserRoleRelationRepository;

        /// <summary>
        /// 角色底层仓储
        /// </summary>
        private readonly ISysRoleRepository _sysRoleRepository;

        /// <summary>
        /// 菜单仓储接口
        /// </summary>
        private readonly ISysMenuRepository _menuRepository;

        /// <summary>
        /// 基础服务
        /// </summary>
        private readonly IBaseService _baseService;

        /// <summary>
        /// 构造实列化
        /// </summary>
        /// <param name="sysUserRepository"></param>
        /// <param name="httpContextAccessor"></param>
        /// <param name="sysCorporationRepository"></param>
        /// <param name="sysUserRoleRelationRepository"></param>
        public SysUserService(ISysUserRepository sysUserRepository, ISysCorporationRepository sysCorporationRepository, ISysUserRoleRelationRepository sysUserRoleRelationRepository, ISysRoleRepository sysRoleRepository, ISysMenuRepository menuRepository, ISysSystemRepository sysSystemRepository, IBaseService baseService)
        {
            _sysUserRepository = sysUserRepository;
            _sysCorporationRepository = sysCorporationRepository;
            _sysCorporationRepository = sysCorporationRepository;
            _sysUserRoleRelationRepository = sysUserRoleRelationRepository;
            _sysRoleRepository = sysRoleRepository;
            _menuRepository = menuRepository;
            _sysSystemRepository = sysSystemRepository;
            _baseService = baseService;
        }

        #endregion

        #region 业务逻辑

        /// <summary>
        /// 根据条件获取用户
        /// </summary>
        /// <param name="corporationKey">公司key</param>
        /// <param name="departmentId">部门key</param>
        /// <returns></returns>
        public ReceiveStatus<SysUserOutPut> GetUser(string corporationKey, string? departmentId)
        {
            ReceiveStatus<SysUserOutPut> receiveStatus = new();
            var result = _baseService.GetAuthWhere(RuleTypeEnum.DataRowRule, "su");
            string? authWhere = string.Empty;
            if (result.success) { authWhere = result.data[0]; }
            else
                ExceptionHelper.ThrowBusinessException(result.msg);
            var list = _sysUserRepository.GetUser(corporationKey, departmentId, authWhere);
            receiveStatus.data = list;
            return receiveStatus;
        }

        /// <summary>
        /// 获取公司人员
        /// </summary>
        /// <param name="pageResultModel"></param>
        /// <returns></returns>
        public PageResultModel<SysUserOutPut> GetCorporationUser(PageResultModel pageResultModel)
        {
            var selectWhere = string.Empty;
            JObject jobj = JObject.Parse(pageResultModel.filterJson ?? string.Empty);
            var menuId = jobj["MenuId"].ToString();

            if (!string.IsNullOrWhiteSpace(menuId))
            {
                var menuModel = _menuRepository.GetByKey(menuId, BaseSqlRepository.sysMenu_selectByKeySql);
                selectWhere = string.Format("and  su.CorporationKey = '{0}'  ", menuModel.CorporationKey);
            }
            pageResultModel.selectWhere = selectWhere;

            pageResultModel.tableField = " su.*,sc.CorporationName,sd.DepartmentName ";
            pageResultModel.tableName = @" Sys_User as su
                                      inner join Sys_Corporation as sc on su.CorporationKey = sc.CorporationKey
                                      inner join Sys_Department as sd on su.DepartmentId = sd.Id ";
            pageResultModel.orderByField = " su.CreateTime ";
            pageResultModel.sortType = " desc ";
            var list = _sysUserRepository.GetPageList<SysUserOutPut>(pageResultModel);
            return list;
        }
        /// <summary>
        /// 根据用户名称和密码获取用户信息
        /// </summary>
        /// <param name="userName">用户名称</param>
        /// <param name="password">用户密码</param>
        /// <param name="corporationKey">公司key</param>
        /// <param name="systemKey">系统key</param>
        /// <returns></returns>
        public ReceiveStatus<LoginOutPut> GetUserMsg(string userName, string password, string corporationKey, string systemKey)
        {
            ReceiveStatus<LoginOutPut> receiveStatus = new ReceiveStatus<LoginOutPut>();
            List<LoginOutPut> loginResultsList = new List<LoginOutPut>();
            if (string.IsNullOrEmpty(userName))
                return ExceptionHelper<LoginOutPut>.CustomExceptionData("用户不能为空！");
            if (string.IsNullOrEmpty(password))
                return ExceptionHelper<LoginOutPut>.CustomExceptionData("密码不能为空！");
            if (string.IsNullOrEmpty(corporationKey))
                return ExceptionHelper<LoginOutPut>.CustomExceptionData("登录公司不能为空！");
            if (string.IsNullOrEmpty(systemKey))
                return ExceptionHelper<LoginOutPut>.CustomExceptionData("登录系统不能为空！");

            //验证公司
            var corporationModel = _sysCorporationRepository.GetByKey(corporationKey, BaseSqlRepository.sysCorporation_selectByKeySql);
            if (corporationModel == null)
                return ExceptionHelper<LoginOutPut>.CustomExceptionData(string.Format("用户【{0}】所在公司已删除", userName));
            if (corporationModel.IsOpen == false)
                return ExceptionHelper<LoginOutPut>.CustomExceptionData(string.Format("用户【{0}】所在公司已停用,请联系管理员", userName));

            //验证公司
            var systemModel = _sysSystemRepository.GetByKey(systemKey, BaseSqlRepository.sysSystem_selectByKeySql);
            if (systemModel == null)
                return ExceptionHelper<LoginOutPut>.CustomExceptionData("当前登录系统不存在或已删除");
            if (systemModel.IsOpen == false)
                return ExceptionHelper<LoginOutPut>.CustomExceptionData("当前登录系统已停用,请联系管理员");

            //验证用户
            var result = _sysUserRepository.GetUserMsg(userName, password, corporationModel.CorporationKey ?? string.Empty);
            if (result == null)
                return ExceptionHelper<LoginOutPut>.CustomExceptionData(string.Format("用户【{0}】不存在,或账号密码输入错误", userName));
            if (result.IsOpen == false)
                return ExceptionHelper<LoginOutPut>.CustomExceptionData(string.Format("用户【{0}】已停用，请开启后再登录", userName));

            var roleIds = string.Empty;
            var userRoleList = _sysUserRoleRelationRepository.GetSysUserRoleRelationsByUserId(result.UserId ?? string.Empty, corporationKey).Where(f => f.IsOpen).ToList();
            if (userRoleList.Count > 0)
                roleIds = string.Join(',', userRoleList.Select(f => f.RoleId));
            else
                return ExceptionHelper<LoginOutPut>.CustomExceptionData(string.Format("用户【{0}】尚未绑定角色或绑定角色未启用", userName));

            LoginOutPut loginResults = new()
            {
                UserId = result.UserId ?? string.Empty,
                UserName = result.UserName ?? string.Empty,
                Token = string.Empty,
                ExpiresDate = string.Empty,
                CorporationKey = result.CorporationKey ?? string.Empty,
                Password = result.Password ?? string.Empty,
                SystemKey = systemKey,
                DepartmentId = result.DepartmentId ?? string.Empty,
                RoleIds = roleIds,
            };
            loginResultsList.Add(loginResults);
            receiveStatus.data = loginResultsList;
            receiveStatus.msg = "登录成功";
            return receiveStatus;
        }

        /// <summary>
        /// 新增用户
        /// </summary>
        /// <param name="sysUser">用户数据</param>
        public ReceiveStatus Insert(SysUser sysUser)
        {
            ReceiveStatus receiveStatus = new();
            var result = Validate(sysUser);
            if (!result.success)
                return result;
            sysUser.UserId = Guid.NewGuid().ToString();
            _sysUserRepository.Insert(sysUser, BaseSqlRepository.sysUser_insertSql);
            return receiveStatus;
        }

        /// <summary>
        /// 修改用户
        /// </summary>
        /// <param name="sysUser">用户数据</param>
        public ReceiveStatus Update(SysUser sysUser)
        {
            ReceiveStatus receiveStatus = new();
            var model = _sysUserRepository.GetByKey(sysUser.UserId.ToString(), BaseSqlRepository.sysUser_selectByKeySql);
            if (model == null)
                return ExceptionHelper.CustomException(string.Format("用户名称【{0}】不存存在或已删除!", sysUser.UserName));
            var result = Validate(sysUser);
            if (!result.success)
                return result;
            if (sysUser.UserId == Const.OverallAuth_NoCloseUser)
            {
                return ExceptionHelper.CustomException(string.Format("用户【{0}】为演示用户，禁止操作。", model.UserName));
            }
            _sysUserRepository.Update(sysUser, BaseSqlRepository.sysUser_updateSql);
            return receiveStatus;
        }

        /// <summary>
        /// 验证
        /// </summary>
        /// <param name="sysUser">用户数据</param>
        /// <returns></returns>
        public ReceiveStatus Validate(SysUser sysUser)
        {
            ReceiveStatus receiveStatus = new ReceiveStatus();
            /*
            新增/修改前验证
            1、用户名称不能出现重复
            2、公司不能为空
            */

            if (string.IsNullOrWhiteSpace(sysUser.UserName))
                return ExceptionHelper.CustomException("用户名称不能为空!");
            if (string.IsNullOrWhiteSpace(sysUser.CorporationKey.ToString()))
                return ExceptionHelper.CustomException("所属公司不能为空!");

            var sysUserModel = _sysUserRepository.GetUserByName(sysUser.CorporationKey, sysUser.UserName);
            if (sysUserModel != null)
            {
                if (sysUserModel.UserName == sysUser.UserName && sysUserModel.UserId != sysUser.UserId)
                    return ExceptionHelper.CustomException(string.Format("用户名称【{0}】已存在,请重新输入!", sysUser.UserName));
            }

            return receiveStatus;
        }

        /// <summary>
        /// 设置用户是否启用
        /// </summary>
        /// <param name="updateIsOpenInPut">修改模型</param>
        /// <returns></returns>
        public ReceiveStatus SetUserIsOpen(UpdateIsOpenInPut updateIsOpenInPut)
        {
            ReceiveStatus receiveStatus = new();
            if (updateIsOpenInPut == null)
                return ExceptionHelper.CustomException("请选择用户");
            if (updateIsOpenInPut.Keys.Count == 0)
                return ExceptionHelper.CustomException("请选择用户");

            var userKey = updateIsOpenInPut.Keys.FirstOrDefault(f => f == Const.OverallAuth_NoCloseUser);
            if (!string.IsNullOrWhiteSpace(userKey))
            {
                var model = _sysUserRepository.GetByKey(userKey, BaseSqlRepository.sysUser_selectByKeySql);
                return ExceptionHelper.CustomException(string.Format("用户【{0}】为演示用户，禁止操作。", model.UserName));
            }

            //写入数据库，加入事务
            TransactionHelper.ExecuteTransaction(() =>
            {
                _sysUserRepository.SetUserIsOpen(updateIsOpenInPut.Keys, updateIsOpenInPut.IsOpen);
            });

            return receiveStatus;
        }

        /// <summary>
        /// 设置用户角色
        /// </summary>
        /// <param name="userOrRoleInput">传入模型</param>
        /// <param name="userId">修改用户id</param>
        public ReceiveStatus SetUserRole(UserRoleInput userOrRoleInput, string userId)
        {
            ReceiveStatus receiveStatus = new ReceiveStatus();
            //if (userOrRoleInput.RoleId.Count == 0)
            //    return ExceptionHelper.CustomException("没有选择任何角色！");
            var userModel = _sysUserRepository.GetByKey(userOrRoleInput.UserId, BaseSqlRepository.sysUser_selectByKeySql);
            if (userModel == null)
                return ExceptionHelper.CustomException("该用户不存在");

            //写入数据库，加入事务
            TransactionHelper.ExecuteTransaction(() =>
            {
                _sysUserRoleRelationRepository.DeleteByUserId(userOrRoleInput.UserId);
                var dateTime = DateTime.Now;
                foreach (var item in userOrRoleInput.RoleId)
                {
                    SysUserRoleRelation sysUserRoleRelation = new SysUserRoleRelation
                    {
                        RoleId = item,
                        UserId = userOrRoleInput.UserId,
                        CreateUser = userId.ToString(),
                        CreateTime = dateTime
                    };
                    _sysUserRoleRelationRepository.Insert(sysUserRoleRelation, BaseSqlRepository.sysUserRoleRelation_insertSql);
                }
            });
            return receiveStatus;
        }

        /// <summary>
        /// 根据用户id获取对应角色
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <param name="corporationKey">公司key</param>
        /// <param name="systemKey">系统key</param>
        /// <returns>返回用户所属角色key</returns>
        public ReceiveStatus<int> GetUserRole(string userId, string corporationKey)
        {
            ReceiveStatus<int> receiveStatus = new();

            //获取用户角色，并验证
            var model = _sysUserRepository.GetByKey(userId, BaseSqlRepository.sysUser_selectByKeySql);
            if (model == null)
                return ExceptionHelper<int>.CustomExceptionData("用户不存在或已停用");

            var userRoleList = _sysUserRoleRelationRepository.GetSysUserRoleRelationsByUserId(userId, corporationKey);
            var roleIdList = userRoleList.Select(f => f.RoleId).ToList();

            receiveStatus.data = roleIdList;
            return receiveStatus;
        }

        /// <summary>
        /// 获取公司人员
        /// </summary>
        /// <param name="corporationKey"></param>
        /// <returns></returns>
        public ReceiveStatus<TreeOutPut> GetCorporationUser(string corporationKey)
        {
            ReceiveStatus<TreeOutPut> receiveStatus = new();
            if (string.IsNullOrEmpty(corporationKey))
                return ExceptionHelper<TreeOutPut>.CustomExceptionData("公司不能为空！");

            //公司信息
            var corporationModel = _sysCorporationRepository.GetByKey(corporationKey, BaseSqlRepository.sysCorporation_selectByKeySql);
            if (corporationModel == null)
                return ExceptionHelper<TreeOutPut>.CustomExceptionData("公司不存在！");
            if (corporationModel.IsOpen == false)
                return ExceptionHelper<TreeOutPut>.CustomExceptionData("公司已停用，不能设置！");
            var userList = _sysUserRepository.GetCorporationUser(corporationKey);
            foreach (var item in userList)
            {
                if (item.key == Const.OverallAuth_NoCloseUser)
                    item.disabled = true;
            }
            var tree = userList.ConvertTreeData();
            receiveStatus.data = tree;
            return receiveStatus;
        }

        /// <summary>
        /// 获取绑定用户
        /// </summary>
        /// <param name="roleId"></param>
        /// <param name="corporationKey"></param>
        /// <returns></returns>
        public ReceiveStatus<string> GetBindUser(int roleId, string corporationKey)
        {
            ReceiveStatus<string> receiveStatus = new ReceiveStatus<string>();
            List<string?> userKeys = new();

            if (string.IsNullOrWhiteSpace(corporationKey))
                return ExceptionHelper<string>.CustomExceptionData("请先登录");
            if (roleId > 0)
            {
                //获取角色
                var roleModel = _sysRoleRepository.GetByKey(roleId.ToString(), BaseSqlRepository.sysRole_selectByKeySql);
                if (roleModel == null)
                    return ExceptionHelper<string>.CustomExceptionData(string.Format("角色id为【{0}】的角色不存在", roleId));

                var userRoleRelationsList = _sysUserRoleRelationRepository.GetSysUserRoleRelationsByRoleId(roleId);
                userKeys = userRoleRelationsList.Select(s => s.UserId).ToList();
            }

            receiveStatus.data = userKeys;
            receiveStatus.msg = "获取成功";
            return receiveStatus;
        }

        /// <summary>
        /// 根据公司key,获取用户
        /// </summary>
        /// <param name="corporationKey">公司key</param>
        /// <returns></returns>
        public ReceiveStatus<SelectOutPut> GetUserByCorporationKey(string corporationKey)
        {
            if (string.IsNullOrWhiteSpace(corporationKey))
                return ExceptionHelper<SelectOutPut>.CustomExceptionData("请选择公司");
            ReceiveStatus<SelectOutPut> receiveStatus = new();
            List<SelectOutPut> selectOutPuts = new();
            var list = _sysUserRepository.GetUserByCorporationKey(corporationKey);
            foreach (var item in list)
            {
                SelectOutPut selectOutPut = new()
                {
                    value = item.UserId ?? string.Empty,
                    label = item.UserName ?? string.Empty,
                    disabled = item.IsOpen == true ? false : true,
                };
                selectOutPuts.Add(selectOutPut);
            }
            receiveStatus.data = selectOutPuts;
            receiveStatus.msg = "获取成功";
            return receiveStatus;
        }

        /// <summary>
        /// 获取所有用户
        /// </summary>
        /// <param name="corporationKey">公司key</param>
        /// <returns></returns>
        public ReceiveStatus<SysUser> GetAllUser(string corporationKey)
        {
            if (string.IsNullOrWhiteSpace(corporationKey))
                return ExceptionHelper<SysUser>.CustomExceptionData("请选择公司");
            ReceiveStatus<SysUser> receiveStatus = new();
            var list = _sysUserRepository.GetUserByCorporationKey(corporationKey);
            receiveStatus.data = list;
            receiveStatus.msg = "获取成功";
            return receiveStatus;
        }
        #endregion
    }
}
